package com.sinosoft.cloud.access.net;

import com.sinosoft.cloud.access.codec.AccessDecoder;
import com.sinosoft.cloud.access.handler.RouterReviceHandler;
import com.sinosoft.cloud.common.SpringContextUtils;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.timeout.ReadTimeoutHandler;

import java.util.concurrent.TimeUnit;

/**
 * cloud-netty
 *
 * @title: cloud-netty
 * @package: com.sinosoft.cloud.access.net
 * @author: yangming
 * @date: 2017/12/3 下午2:41
 */
public class RouterChannelInitializer extends AbstractAccessInitializer {

    private String ip;
    private final ChannelHandlerContext ctx;
    private final Object msg;
    private final MessageObject messageObject;

    AccessControl accessControl = SpringContextUtils.getBeanByClass(AccessControl.class);

    public RouterChannelInitializer(ChannelHandlerContext ctx, Object msg,MessageObject messageObject) {
        this.ctx = ctx;
        this.msg = msg;
        this.messageObject = messageObject;
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    @Override
    protected void initChannel(Channel channel) throws Exception {
        ChannelPipeline pipeline = channel.pipeline();
        addRouterHandler(pipeline);


    }


    /**
     * 路由处理逻辑比较简单, 连接时原样发送,接收返回消息时进行长度判断
     *
     * @param pipeline
     */
    private void addRouterHandler(ChannelPipeline pipeline) {
        /*加入接收消息超时解码器*/
        initReadTimeoutHandler(pipeline);
        /*现进行Decoder(处理报文头,将消息接受完整)*/
        initRouterDecoder(pipeline);
        /*从路由目标端返回后处理*/
        initRouterReviceHandler(pipeline);
    }

    /**
     * 返回后处理
     *
     * @param pipeline
     */
    private void initRouterReviceHandler(ChannelPipeline pipeline) {
        RouterReviceHandler routerReviceHandler = new RouterReviceHandler(this.ctx,this.messageObject);
        routerReviceHandler.setAccessName(getAccessName());
        routerReviceHandler.setPort(getPort());
        pipeline.addLast(routerReviceHandler);
    }

    /**
     * @param pipeline
     */
    private void initRouterDecoder(ChannelPipeline pipeline) {
        AccessDecoder accessDecoder = new AccessDecoder();
        accessDecoder.setAccessName(this.getAccessName());
        accessDecoder.setPort(this.getPort());
        pipeline.addLast(accessDecoder);
    }

    /**
     * @param pipeline
     */
    private void initReadTimeoutHandler(ChannelPipeline pipeline){
        pipeline.addLast(new ReadTimeoutHandler(accessControl.getCipReturnTimeOut(), TimeUnit.MILLISECONDS));
    }
}
